<p>This rule raises an issue when the <code>forEach</code> method is called on arrays, as <code>for…​of</code> loops provide more control flow
options.</p>
<h2>Why is this an issue?</h2>
<p>The usage of <code>forEach</code> limits your control flow options. You cannot use <code>break</code> to exit early or <code>continue</code> to
skip iterations, as these statements don’t work inside callback functions. This forces developers to use workarounds like throwing exceptions or
complex conditional logic.</p>
<p>Additionally, <code>forEach</code> doesn’t work properly with async/await. The callback function in <code>forEach</code> is called for each element
immediately without waiting for any asynchronous operations to complete, which can lead to unexpected behavior when processing arrays that require
async operations.</p>
<p>In TypeScript projects, <code>forEach</code> creates a function boundary that breaks type narrowing. Variables that were narrowed to specific types
before the loop may lose their narrowed type inside the callback. Additionally, TypeScript’s analysis of variable mutations can be disrupted by the
function boundary, potentially missing important usage patterns.</p>
<p>The <code>for…​of</code> loop syntax is also more readable and familiar to developers coming from other programming languages, making the code
easier to understand and maintain.</p>
<h3>What is the potential impact?</h3>
<p>Using <code>forEach</code> instead of <code>for…​of</code> can lead to:</p>
<ul>
  <li> Limited control flow capabilities, preventing early exits and iteration skipping </li>
  <li> Type safety issues in TypeScript where type narrowing is lost across function boundaries </li>
  <li> Reduced code maintainability due to less intuitive syntax for simple iterations </li>
</ul>
<h3>How to fix?</h3>
<p>Replace simple <code>forEach</code> calls with <code>for…​of</code> loops.</p>
<h4>Non-compliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
array.forEach(element =&gt; {
    console.log(element);
}); // Noncompliant

array.forEach((element, index) =&gt; {
	console.log(element, index);
}); // Noncompliant

// Doesn't work as expected with async operations
urls.forEach(async (url) =&gt; {
    const response = await fetch(url); // These requests happen concurrently, not sequentially
    console.log(response.status);
}); // Noncompliant
</pre>
<h4>Compliant code example</h4>
<pre data-diff-id="1" data-diff-type="compliant">
for (const element of array) {
    console.log(element);
}

for (const [index, element] of array.entries()) {
	console.log(element, index);
}

// Properly handles async operations sequentially
for (const url of urls) {
    const response = await fetch(url); // These requests happen one after another
    console.log(response.status);
}
</pre>
<h3>Documentation</h3>
<ul>
  <li> <a href="https://github.com/sindresorhus/eslint-plugin-unicorn#readme">eslint-plugin-unicorn</a> - Rule <a
  href="https://github.com/sindresorhus/eslint-plugin-unicorn/blob/HEAD/docs/rules/no-array-for-each.md">no-array-for-each</a> </li>
  <li> MDN: for…​of statement - <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for…​of">Complete guide to
  for…​of loops in JavaScript</a> </li>
  <li> MDN: Array.prototype.forEach() - <a
  href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">Documentation for the forEach method</a> </li>
  <li> MDN: Array.prototype.entries() - <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries">How
  to get both index and value in iterations</a> </li>
</ul>
